import express, { Request, Response } from 'express';
import Vote from '../models/Vote';
import { authMiddleware } from '../middleware/authMiddleware';
import mongoose from 'mongoose';
import { getMyJoinedVotes } from '../controllers/voteController';
import { ethers } from 'ethers';
import votingFactoryAbi from '../chain/votingFactoryAbi.json';
import { votingFactoryAddress } from '../chain/votingFactory';

const router = express.Router();

// 创建投票（需登录）
router.post('/create', authMiddleware, async (req: Request, res: Response) => {
  const { voteName, candidates, inviteCode, expireSeconds, maxVoters, chainVoteId } = req.body;
  // 参数校验
  if (!voteName || !Array.isArray(candidates) || candidates.length === 0) {
    return res.status(400).json({ success: false, message: '参数错误' });
  }
  if (!inviteCode || typeof inviteCode !== 'string' || !/^[A-Za-z0-9]{16}$/.test(inviteCode)) {
    return res.status(400).json({ success: false, message: '邀请码格式错误' });
  }
  if (!expireSeconds || !Number.isInteger(expireSeconds) || expireSeconds < 1 || expireSeconds > 604800) {
    return res.status(400).json({ success: false, message: '有效期参数错误' });
  }
  if (!maxVoters || !Number.isInteger(maxVoters) || maxVoters < 1) {
    return res.status(400).json({ success: false, message: '最大投票人数参数错误' });
  }
  if (chainVoteId === undefined || chainVoteId === null || isNaN(chainVoteId)) {
    return res.status(400).json({ success: false, message: '链上ID无效' });
  }
  // 校验邀请码唯一性
  const exists = await Vote.findOne({ inviteCode });
  if (exists) {
    return res.status(400).json({ success: false, message: '邀请码已存在，请重试' });
  }
  // 校验链上ID唯一性
  const duplicateVote = await Vote.findOne({ chainVoteId });
  if (duplicateVote) {
    return res.status(400).json({ success: false, message: '该链上ID已被其他投票使用' });
  }
  // 计算过期时间
  const expireAt = new Date(Date.now() + expireSeconds * 1000);
  try {
    const vote = await Vote.create({
      voteName,
      creator: (req as any).user.userId,
      inviteCode,
      candidates,
      expireAt,
      maxVoters,
      currentVoters: 0,
      expired: false,
      chainVoteId
    });
    res.json({
      success: true,
      message: '投票创建成功',
      data: {
        voteId: vote._id,
        inviteCode: vote.inviteCode,
        voteName: vote.voteName,
        candidates: vote.candidates,
        expireAt: vote.expireAt,
        maxVoters: vote.maxVoters,
        currentVoters: vote.currentVoters,
        chainVoteId: vote.chainVoteId
      }
    });
  } catch (err: any) {
    res.status(500).json({ success: false, message: '创建失败', error: err.message || String(err) });
  }
});

// 查询我参与的投票（链上查询，前端传钱包地址）
router.get('/my-joined', getMyJoinedVotes);

// 通过邀请码查询投票基本信息
router.get('/by-invite/:inviteCode', async (req: Request, res: Response) => {
  const { inviteCode } = req.params;
  if (!inviteCode || typeof inviteCode !== 'string' || !/^[A-Za-z0-9]{16}$/.test(inviteCode)) {
    return res.status(400).json({ success: false, message: '邀请码格式错误' });
  }
  const vote = await Vote.findOne({ inviteCode });
  if (!vote) {
    return res.status(404).json({ success: false, message: '邀请码不存在' });
  }
  // 检查是否过期
  const expired = vote.expireAt < new Date();
  if (expired) {
    // 更新过期状态
    await Vote.findByIdAndUpdate(vote._id, { expired: true });
  }
  res.json({
    success: true,
    data: {
      voteId: vote._id,
      voteName: vote.voteName,
      expired,
      maxVoters: vote.maxVoters,
      currentVoters: vote.currentVoters
    }
  });
});

// 查询我创建的投票（需登录）
router.get('/my-created', authMiddleware, async (req: Request, res: Response) => {
  try {
    const userId = (req as any).user.userId;
    const votes = await Vote.find({ creator: new mongoose.Types.ObjectId(userId) });
    // 更新过期状态
    const now = new Date();
    const updatedVotes = votes.map(vote => {
      const expired = vote.expireAt < now;
      if (expired && !vote.expired) {
        Vote.findByIdAndUpdate(vote._id, { expired: true }).catch(console.error);
      }
      return { ...vote.toObject(), expired };
    });
    res.json({ success: true, data: updatedVotes });
  } catch (err) {
    res.status(500).json({ success: false, message: '服务器错误' });
  }
});

// 绑定链上投票ID（需登录，链下与链上数据关联）
router.post('/bind-chain-id', authMiddleware, async (req: Request, res: Response) => {
  const { _id, chainVoteId } = req.body;
  console.log('绑定链上ID请求参数:', { _id, chainVoteId });
  
  if (!_id || chainVoteId === undefined || chainVoteId === null || isNaN(chainVoteId)) {
    console.error('参数错误:', { _id, chainVoteId });
    return res.status(400).json({ success: false, message: '参数错误' });
  }
  
  try {
    // 先检查投票是否存在
    const existingVote = await Vote.findById(_id);
    if (!existingVote) {
      console.error('投票不存在:', _id);
      return res.status(404).json({ success: false, message: '投票不存在' });
    }

    // 检查是否已经绑定过
    if (existingVote.chainVoteId) {
      console.error('投票已绑定链上ID:', existingVote.chainVoteId);
      return res.status(400).json({ success: false, message: '该投票已绑定链上ID' });
    }

    // 检查chainVoteId是否已被其他投票使用
    const duplicateVote = await Vote.findOne({ chainVoteId });
    if (duplicateVote) {
      console.error('链上ID已被使用:', { chainVoteId, byVoteId: duplicateVote._id });
      return res.status(400).json({ success: false, message: '该链上ID已被其他投票使用' });
    }

    const vote = await Vote.findByIdAndUpdate(
      _id,
      { chainVoteId: Number(chainVoteId) },
      { new: true }
    );

    if (!vote) {
      console.error('更新失败:', _id);
      return res.status(500).json({ success: false, message: '更新失败' });
    }

    console.log('绑定成功:', { voteId: _id, chainVoteId });
    res.json({ 
      success: true, 
      message: '绑定成功',
      data: vote 
    });
  } catch (err: any) {
    console.error('绑定链上ID失败:', err);
    res.status(500).json({ 
      success: false, 
      message: '绑定链上ID失败',
      error: err.message || String(err)
    });
  }
});

// 添加自定义候选
router.post('/:voteId/add-candidate', async (req: Request, res: Response) => {
  const { voteId } = req.params;
  const { name, signature, imageUrl, address } = req.body;

  if (!voteId || !name || !address) {
    return res.status(400).json({ success: false, message: '参数错误' });
  }

  try {
    const vote = await Vote.findById(voteId);
    if (!vote) {
      return res.status(404).json({ success: false, message: '投票不存在' });
    }

    // 检查投票状态
    if (vote.expired || vote.expireAt < new Date()) {
      return res.status(400).json({ success: false, message: '投票已结束' });
    }

    // 检查是否已投票
    if (vote.voterAddresses && vote.voterAddresses.includes(address.toLowerCase())) {
      return res.status(400).json({ success: false, message: '您已经投票，不能添加候选' });
    }

    // 查重
    const existingCandidate = vote.candidates.find(
      c => c.name.trim().toLowerCase() === name.trim().toLowerCase()
    );
    if (existingCandidate) {
      return res.status(400).json({ success: false, message: '该候选名称已存在，请使用其他名称' });
    }

    // 添加新候选
    const newCandidate = {
      name: name.trim(),
      signature: signature?.trim() || "",
      imageUrl: imageUrl || "",
      addedBy: address.toLowerCase(),
      isCustom: true,
      addedAt: new Date()
    };

    // 使用 $push 操作符添加候选
    const updatedVote = await Vote.findByIdAndUpdate(
      voteId,
      { $push: { candidates: newCandidate } },
      { new: true }
    );

    if (!updatedVote) {
      throw new Error('更新失败');
    }

    res.json({
      success: true,
      message: '添加候选成功',
      data: newCandidate
    });

  } catch (err: any) {
    console.error('添加候选失败:', err);
    res.status(500).json({ 
      success: false, 
      message: '添加候选失败',
      error: err.message || String(err)
    });
  }
});

// 记录参与者地址（投票或弃权后调用）
router.post('/record-voter', async (req, res) => {
  const { voteId, address } = req.body;
  if (!voteId || !address) {
    return res.status(400).json({ success: false, message: '参数错误' });
  }
  try {
    await Vote.findByIdAndUpdate(
      voteId,
      { $addToSet: { voterAddresses: address.toLowerCase() } }
    );
    res.json({ success: true });
  } catch (err) {
    res.status(500).json({ success: false, message: '服务器错误' });
  }
});

// 通过投票ID查询投票详情（含过期判断）
// 注意：此路由要放最后，避免与前面路由冲突
router.get('/:voteId', async (req: Request, res: Response) => {
  const { voteId } = req.params;
  if (!mongoose.Types.ObjectId.isValid(voteId)) {
    return res.status(404).json({ success: false, message: '投票不存在' });
  }
  try {
    const vote = await Vote.findById(voteId);
    if (!vote) {
      return res.status(404).json({ success: false, message: '投票不存在' });
    }
    // 判断是否过期
    const expired = vote.expireAt < new Date();
    if (expired && !vote.expired) {
      // 更新过期状态
      await Vote.findByIdAndUpdate(vote._id, { expired: true });
    }
    res.json({
      success: true,
      data: {
        ...vote.toObject(),
        expired,
        maxVoters: vote.maxVoters,
        currentVoters: vote.currentVoters,
        voterAddresses: vote.voterAddresses || []
      }
    });
  } catch (err) {
    res.status(500).json({ success: false, message: '服务器错误' });
  }
});

export default router;